/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ADT;
import Interfaces.BoundingBox;
import Interfaces.Length;

/**
 *
 * @author markusbaisch
 */
public class BoundingBoxImpl implements BoundingBox {

    // Member
    private final Length length;
    private final Length width;
    private final Length height;

    // Konstruktor
    private BoundingBoxImpl( Length length, Length width, Length height ) {
        this.length = length;
        this.width = width;
        this.height = height;
    }

    public static BoundingBox valueOf( Length length, Length width, Length height ) {
        return new BoundingBoxImpl( length, width, height );
    }

    public int hashCode() {
        return length.hashCode() + width.hashCode()*2 + height.hashCode()*3;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof BoundingBoxImpl)) return false;
        return this.compareTo((BoundingBoxImpl) o) == 0;
    }

    // Rest
    @Override
    public Length length() {
        return length;
    }

    @Override
    public Length width() {
        return width;
    }

    @Override
    public Length height() {
        return height;
    }

    @Override
    public boolean fitsInto(BoundingBox Value) {
        return ( length.sub(Value.length()).m() > 0 && width.sub(Value.width()).m() > 0 && height.sub(Value.height()).m() > 0);
    }

    @Override
    public BoundingBox add(BoundingBox Value) {
        return valueOf( (length.add( Value.length() )), (width.add( Value.width() )), (height.add( Value.height() )) );
    }

    @Override
    public BoundingBox sub(BoundingBox Value) {
        return valueOf( (length.sub( Value.length() )), (width.sub( Value.width() )), (height.sub( Value.height() )) );
    }

    @Override
    public BoundingBox mul(double faktor) {
        return valueOf( (length.mul( faktor )), (width.mul( faktor )), (height.mul( faktor )) );
    }

    @Override
    public BoundingBox div(double faktor) {
        return valueOf( (length.div( faktor )), (width.div( faktor )), (height.div( faktor )) );
    }

    @Override
    public double div(BoundingBox Value) {
        // Nur ein Double können wir nicht
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public BoundingBox inverse() {
        return valueOf( length.inverse(), width.inverse(), height.inverse() );
    }

    @Override
    public int compareTo(BoundingBox Value) {
        // Gleichgroß
        if ( length.m() == Value.length().m() && width.m() == Value.width().m() && height.m() == Value.height().m() ) return 0;
        else if( volume() > Value.volume() ) return 1;
        else return -1;
    }

    @Override
    public double getValue() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public boolean isZero() {
        return length.isZero() && width.isZero() && height.isZero();
    }

    @Override
    public boolean isValid() {
        return length.isValid() && width.isValid() && height.isValid();
    }

    @Override
    // Volumen
    public double volume()
    {
        return length.m() * width.m() * height.m();
    }

}
